using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using Zhaoxi.Zhihu.UseCases.Common.Exceptions;

namespace Zhaoxi.Zhihu.HttpApi.Infrastructure;

public class UerCaseExceptionHandler: IExceptionHandler
{
    private readonly Dictionary<Type, Func<HttpContext, Exception, Task>> _exceptionHandlers;

    public UerCaseExceptionHandler()
    {
        _exceptionHandlers = new Dictionary<Type, Func<HttpContext, Exception, Task>>
        {
            
            {typeof(ForbiddenException),HandlerForbiddenExceptionAsync},
            {typeof(ValidationException),HandlerValidationException}
            

        };
    }

    private static async Task HandlerValidationException(HttpContext httpContext, Exception exception)
    {
        var validationException=(ValidationException)exception;
        httpContext.Response.StatusCode=StatusCodes.Status400BadRequest;
        await httpContext.Response.WriteAsJsonAsync(new ValidationProblemDetails(validationException.Errors)
        {
            Status=StatusCodes.Status400BadRequest,
                Type="ValidationException",
        });
    }


    public  async ValueTask<bool> TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
    {
        var exceptionType = exception.GetType();
        if (!_exceptionHandlers.TryGetValue(exceptionType, out var handler))return false;
        
        await handler.Invoke(httpContext,exception);
        return true;
    }
    
    private static async Task HandlerForbiddenExceptionAsync(HttpContext httpContent, Exception exception)
    {
       httpContent.Response.StatusCode= StatusCodes.Status403Forbidden;
       
       await httpContent.Response.WriteAsJsonAsync(new ProblemDetails
       {
           Status = StatusCodes.Status403Forbidden,
           Title = "Forbidden",
           Type = "https://httpstatuses.com/403",
       });
    }
}